package com.suxin.thread.manager.threadpool;

import java.util.*;
import java.util.concurrent.ExecutorService;

/**
 * @author Tang
 * @classname ThreadPoolManager
 * @description [  ]
 * @date 2022/8/12 09:33
 */
public class ThreadPoolManager {

    /**
     * 注册表
     */
    private static Map<String, Map<String, Set<ExecutorService>>> resourceMap = null;

    /**
     * 单例
     */
    private final static ThreadPoolManager INSTANCE = new ThreadPoolManager();

    static {
        INSTANCE.init();
        Runtime.getRuntime().addShutdownHook(new Thread(ThreadPoolManager::destroy));
    }

    private void init() {
        resourceMap = new HashMap<>(8);
    }

    public static ThreadPoolManager getInstance() {
        return INSTANCE;
    }

    /**
     * 注册
     * @param namespace
     * @param group
     * @param executorService
     */
    public void register(String namespace, String group, ExecutorService executorService) {
        resourceMap.compute(namespace,(key,oldValue) -> {
            if (oldValue == null) {
                Map<String, Set<ExecutorService>> hashMap = new HashMap<>(4);
                hashMap.put(group, new HashSet<>(Collections.singleton(executorService)));
                return hashMap;
            }
            oldValue.compute(group, (key1, oldValue1) -> {
                if (oldValue1 == null) {
                    return new HashSet<>(Collections.singleton(executorService));
                }
                oldValue1.add(executorService);
                return oldValue1;
            });
            return oldValue;
        });
    }

    /**
     * 销毁 指定 namespace
     * @param namespace namespace
     */
    public static void destroyNameSpace(String namespace) {
        Map<String, Set<ExecutorService>> namespaceMap = resourceMap.get(namespace);
        for (Set<ExecutorService> services : namespaceMap.values()) {
            services.forEach(ExecutorService::shutdown);
        }
    }

    /**
     * 线程池销毁
     */
    public static void destroy() {
        for (String namespace : resourceMap.keySet()) {
            destroyNameSpace(namespace);
        }
    }

}
